﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace ShoppingList
{
    public class ItemViewModel : INotifyPropertyChanged
    {
        private string _itemName;

        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
        /// </summary>
        /// <returns></returns>
        public string ItemName
        {
            get
            {
                return _itemName;
            }
            set
            {
                if (value != _itemName)
                {
                    _itemName = value;
                    NotifyPropertyChanged("ItemName");
                }
            }
        }

        private decimal _amount;

        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
        /// </summary>
        /// <returns></returns>
        public decimal Amount
        {
            get
            {
                return _amount;
            }
            set
            {
                if (value != _amount)
                {
                    _amount = value;
                    NotifyPropertyChanged("Amount");
                    this.NotifyPropertyChanged("Sum");
                    this.NotifyPropertyChanged("PriceInfo");
                    this.NotifyPropertyChanged("ItemSumVisible");
                }
            }
        }

        private string _comment;

        /// <summary>
        /// Sample ViewModel property; this property is used in the view to display its value using a Binding.
        /// </summary>
        /// <returns></returns>
        public string Comment
        {
            get
            {
                return _comment;
            }
            set
            {
                if (value != _comment)
                {
                    _comment = value;
                    NotifyPropertyChanged("Comment");
                }
            }
        }

        private bool _selected;

        /// <summary>
        /// Gets or sets the selected.
        /// </summary>
        /// <value>The selected.</value>
        [System.Xml.Serialization.XmlIgnore]
        public bool Selected
        {
            get
            {
                return this._selected;
            }

            set
            {
                if (value != this._selected)
                {
                    this._selected = value;

                    this.NotifyPropertyChanged("Selected");
                    this.NotifyPropertyChanged("ItemSumVisible");
                }
            }
        }

        [System.Xml.Serialization.XmlIgnore]
        public bool ItemSumVisible
        {
            get
            {
                return Selected && Amount != 1m;
            }
        }

        private decimal _price;

        /// <summary>
        /// Gets or sets the Price.
        /// </summary>
        /// <value>The Price.</value>
        public decimal Price
        {
            get
            {
                return this._price;
            }

            set
            {
                if (value != this._price)
                {
                    this._price = value;

                    this.NotifyPropertyChanged("Price");
                    this.NotifyPropertyChanged("Sum");
                    this.NotifyPropertyChanged("PriceInfo");
                }
            }
        }

        /// <summary>
        /// Gets or sets the Price.
        /// </summary>
        /// <value>The Price.</value>
        [System.Xml.Serialization.XmlIgnore]
        public string Sum
        {
            get
            {
                return (this.Price * this.Amount).ToString("n2");
            }
        }

        /// <summary>
        /// Gets or sets the price info.
        /// </summary>
        /// <value>The price info.</value>
        [System.Xml.Serialization.XmlIgnore]
        public string PriceInfo
        {
            get
            {
                return string.Format("({0}x{1})", this.Amount.ToString(), this.Price.ToString());
            }
        }

        //private bool _bought;

        ///// <summary>
        ///// Gets or sets the bought flag.
        ///// </summary>
        ///// <value>The bought flag.</value>
        //public bool IsBought
        //{
        //    get
        //    {
        //        return this._bought;
        //    }

        //    set
        //    {
        //        if (value != this._bought)
        //        {
        //            this._bought = value;

        //            this.NotifyPropertyChanged("IsBought");
        //        }
        //    }
        //}

        public event PropertyChangedEventHandler PropertyChanged;

        internal void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public static Comparison<ItemViewModel> NameComparison = new Comparison<ItemViewModel>(CompareByName);
        public static Comparison<ItemViewModel> UnitPriceComparison = new Comparison<ItemViewModel>(CompareByUnitPrice);
        public static Comparison<ItemViewModel> PriceComparison = new Comparison<ItemViewModel>(CompareByPrice);

        private static int CompareByName(ItemViewModel item1, ItemViewModel item2)
        {
            return string.Compare(item1.ItemName, item2.ItemName);
        }

        private static int CompareByUnitPrice(ItemViewModel item1, ItemViewModel item2)
        {
            return decimal.Compare(item1.Price, item2.Price);
        }

        private static int CompareByPrice(ItemViewModel item1, ItemViewModel item2)
        {
            return decimal.Compare(item1.Price * item1.Amount, item2.Price * item2.Amount);
        }
    }
}